package me.zhengjie.modules.system.domain

import cn.hutool.core.bean.BeanUtil
import cn.hutool.core.bean.copier.CopyOptions
import com.alibaba.fastjson.annotation.JSONField
import com.fasterxml.jackson.annotation.JsonTypeName
import io.swagger.v3.oas.annotations.media.Schema
import jakarta.persistence.*
import jakarta.validation.constraints.NotNull
import me.zhengjie.common.base.BaseEntity
import me.zhengjie.common.utils.JacksonUtil
import org.hibernate.annotations.CreationTimestamp
import org.springframework.data.redis.core.RedisHash
import java.sql.Timestamp
import java.util.*

/**
 * @author Kuki Wu
 * @date 2024-11-20
 */
@Entity
@Table(name = "sys_menu")
@JsonTypeName("sysmenu")
@RedisHash("sysmenu")
data class Menu(
    @Id
    @Column(name = "menu_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Schema(description = "ID", hidden = true)
    val id: @NotNull(groups = [Update::class]) Long? = null,

    @JSONField(serialize = false)
    @ManyToMany(mappedBy = "menus")
    @Schema(description = "菜单角色")
    var roles: Set<Role>? = null,

    @Schema(description = "菜单标题")
    var title: String? = null,

    @Column(name = "name")
    @Schema(description = "菜单组件名称")
    var componentName: String? = null,

    @Schema(description = "排序")
    var menuSort: Int? = 999,

    @Schema(description = "组件路径")
    var component: String? = null,

    @Schema(description = "路由地址")
    var path: String? = null,

    // 类型
    @Schema(description = "菜单类型，目录、菜单、按钮")
    var type: Int? = null,

    // 权限
    @Schema(description = "权限标识")
    var permission: String? = null,

    @Schema(description = "菜单图标")
    var icon: String? = null,

    @Column(columnDefinition = "bit(1) default 0")
    @Schema(description = "缓存")
    var cache: Boolean? = null,

    @Column(columnDefinition = "bit(1) default 0")
    @Schema(description = "是否隐藏")
    var hidden: Boolean? = null,

    // 上级菜单ID
    @Schema(description = "上级菜单")
    var pid: Long? = null,

    @Schema(description = "子节点数目", hidden = true)
    var subCount: Int? = 0,

    // 是否为外链 true/false
    @Schema(description = "外链菜单")
    var iFrame: Boolean? = null
):BaseEntity(){
    annotation class Update

    companion object {
        fun fromJson(json: String): Menu? {
            val obj = JacksonUtil.parseObject(json, Menu::class.java)!!
            return when (obj) {
                is Menu -> obj
                else -> null
            }
        }
    }
    

    fun copy(source: Menu?) {
        BeanUtil.copyProperties(source, this, CopyOptions.create().setIgnoreNullValue(true))
    }
}